home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / ASTRONOM / H139.ZIP / RO101.ZIP / RO_OUTP.C < prev    next >
C/C++ Source or Header  |  1991-11-04  |  12KB  |  580 lines

  1. /********************************************************/
  2. /*                            */
  3. /*    ro_outp.c    output routines for ro        */
  4. /*                            */
  5. /*    ro version 1.10                    */
  6. /*                            */
  7. /*    Portions copyright (c) 1990 by Ted A. Campbell    */
  8. /*        Bywater Software            */
  9. /*        P. O. Box 4023                */
  10. /*        Duke Station                */
  11. /*        Durham, NC  27706            */
  12. /*                            */
  13. /*    Contains portions of ROFF4, Version 1.60    */
  14. /*      (c) 1983, 4 by Ernest E. Bergmann               */
  15. /*        Physics, Building #16            */
  16. /*        Lehigh University            */
  17. /*        Bethlehem, Pa. 18015            */
  18. /*                            */
  19. /*    Contains portions of ROFF4, Version 1.61    */
  20. /*      (c) 1985 by Konrad Kwok                         */
  21. /*        20 3rd Street, Section M        */
  22. /*        Fariview Park,                */
  23. /*        Hong Kong                */
  24. /*                            */
  25. /*    ro and its predecessor ROFF4 are based on     */
  26. /*    the ROFF text processor described in Kernigan    */
  27. /*    and Plauger's now-classic text <Software Tools> */
  28. /*                            */
  29. /* Permission is hereby granted for all commercial and    */
  30. /* non-commercial reproduction and distribution of this */
  31. /* material provided this notice is included.        */
  32. /*                            */
  33. /********************************************************/
  34.  
  35. #include "ro.h"
  36.  
  37. /*assuming REVSCROLL is FALSE*/
  38. /*output ro_out2buf with the vertical height of the mainline
  39. specified by ro_vlineno,ro_vflineno[they must not be changed here].
  40. Excessive superscripting will be pushed down.*/
  41.  
  42. printout()
  43.    {
  44.    int level, top, bot;       /* "up" is negative; units fractional */
  45.    int lsave;
  46.    register int n;
  47.  
  48.    ro_out2buf[ ro_bpos ] = '\0';           /* terminate with '\0' */
  49.    lsave = ro_vlineno;
  50.    level = ro_plineno - ro_vlineno;
  51.  
  52.    if ( !ro_oldbot )
  53.       {
  54.       level++;
  55.       }
  56.  
  57.    excurs( &ro_out2buf[0], &top, &bot );
  58.  
  59.    if ( top > level )
  60.       {
  61.       level=top;
  62.       }
  63.  
  64.    padv();
  65.  
  66.    /* output offset spaces at beginning of line */
  67.  
  68.    for ( n = 0; n < ro_poval; ++n )
  69.       {
  70.       ro_outc( ' ' );
  71.       }
  72.  
  73.    for ( ; level <= bot; level++ )
  74.       {
  75.       ro_ocnt = 0;
  76.       do
  77.          {
  78.          ro_ocnt++; 
  79.          flp( level, FALSE );
  80.          }
  81.       while ( retype() );
  82.       }
  83.  
  84.    ro_out2buf[0] = ro_bpos = 0;
  85.    ro_oldln = ro_vlineno = lsave;
  86.    ro_oldbot = bot;
  87.    }
  88.  
  89. /****************************************/
  90. /*moves printer vertically so that its position is specified
  91. by ro_vlineno,ro_vflineno*/
  92.  
  93. padv()
  94.    {
  95.    int w;
  96.  
  97.    w = ro_vlineno - ro_plineno;
  98.    if ( w < 0 )
  99.       {
  100.       if (ro_verbose )
  101.          {
  102.          fprintf( stderr,"padv(): VL=%d, PL=%d\n",
  103.             ro_vlineno, ro_plineno);
  104.          }
  105.       ro_vlineno += w;
  106.       }
  107.    while( w-- )
  108.       {
  109.       ro_outc('\n');
  110.       ro_plineno++;
  111.       }
  112.    }
  113.  
  114. /**************************************************/
  115. /* finds the topmost and bottommost line
  116. positions of str */
  117.  
  118. excurs( str, t, b)
  119.    char *str;
  120.    int *t, *b;
  121.    {
  122.    int l;
  123.    char c;
  124.    *t = *b = l = 0;        /*current line position */
  125.    c = *str;
  126.    while ( c )
  127.       {
  128.       if ( c == ro_cfval[0])
  129.          {
  130.          if ( c = *(++str) )
  131.             {
  132.             switch ( c )
  133.                {
  134.             case '+':
  135.                l--; 
  136.                if ( l < *t )
  137.                   {
  138.                   *t = l;
  139.                   }
  140.                c = *( ++str );
  141.                break;
  142.             case '-':
  143.                l++; 
  144.                if ( l >* b)
  145.                   {
  146.                   *b = l;
  147.                   }
  148.                c = *( ++str );
  149.                break;
  150.             default : 
  151.                c = *( ++str );
  152.                break;
  153.                }
  154.             }
  155.          }
  156.       else c = *( ++str );
  157.       }
  158.    }
  159.  
  160. /**************************************************/
  161. /* fancy line print at a given vertical level
  162. the string in ro_out2buf[] with backspacing,
  163. underlining, and strikout. To permit boldface
  164. it modifies ro_dbuf[], ro_dpos so that retype can be
  165. used to patch up ro_out2buf for resubmittal to
  166. flp() */
  167.  
  168. flp( level, updat )
  169.    int level;   /* current vertical level to print*/
  170.    int updat;   /* boolean for update of ro_uf,ro_xf,ro_mcnt*/
  171.    {
  172.    int i;
  173.  
  174.    ro_blkcnt = lbc( level, ro_out2buf );
  175.    ro_first = TRUE;
  176.  
  177.    while ( (ro_blkcnt > 0 ) || updat )
  178.       {
  179.       prpass( level, updat); 
  180.       ro_outc('\r');
  181.       updat = ro_first = FALSE;
  182.       }
  183.    if ( ro_xcol > -1 )
  184.       {
  185.       for ( i = 0; i <= ro_xcol; i++ )
  186.          {
  187.          ro_outc( ro_xbuf[ i ] );
  188.          }
  189.       ro_outc('\r');
  190.       }
  191.    if ( ro_ucol > -1 )
  192.       {
  193.       for ( i = 0; i <= ro_ucol; i++ )
  194.          {
  195.          ro_outc( ro_ubuf[ i ] );
  196.          }
  197.       ro_outc( '\r' );
  198.       }
  199.    if (( ro_ucol >- 1 ) || ( ro_xcol >-1 )) 
  200.       {
  201.       initxu();
  202.       }
  203.    }
  204.  
  205. /**************************************************/
  206.  
  207. retype()
  208.    {
  209.    int i;
  210.    if ( ro_dpos == -1 )
  211.       {
  212.       return(FALSE);
  213.       }
  214.    else
  215.       {
  216.       for ( i = 0; i <= ro_dpos; i++ )
  217.          {
  218.          if ( ro_dbuf[ i ] )
  219.             {
  220.             ro_out2buf[ i ] = ro_dbuf[ i ];
  221.             ro_dbuf[ i ] = FALSE;
  222.             }
  223.          }
  224.       ro_dpos = -1;
  225.       return( TRUE );
  226.       }
  227.    }
  228.  
  229. /**************************************************/
  230. /*counts printable chars in line level and
  231. above; parity must be reset*/
  232.  
  233. int lbc( lev, str ) 
  234.    int lev;    /* = 0 main line, = -1 superscripts, = +1 subscripts, etc.*/
  235.    char *str;
  236.    {
  237.    char c;
  238.    int l, n;
  239.    l = n = 0;
  240.    c = *str;
  241.    while ( c )
  242.       {
  243.       if ( c == ro_cfval[ 0 ] )
  244.          {
  245.          if ( c = *(++str) )
  246.             {
  247.             switch(c)
  248.                {
  249.             case '+':
  250.                l--;
  251.                c = *(++str);
  252.                break;
  253.             case '-':
  254.                l++;
  255.                c = *(++str);
  256.                break;
  257.             default: 
  258.                c = *(++str);
  259.                break;
  260.                }
  261.             }
  262.          }
  263.       else
  264.          {
  265.          if ( ( c > ' ' ) && ( l <= lev ))
  266.             {
  267.             if ( c != ro_tcval[ 0 ] )
  268.                {
  269.                n++;
  270.                }
  271.             }
  272.          c = *( ++str );
  273.          }
  274.       }
  275.    return ( n );
  276.    }
  277.  
  278. /**************************************************/
  279. /*printer pass initial cr; no lf anywhere*/
  280.  
  281. prpass( lev, updat ) 
  282.    int lev;    /* = 0 main line, = -1 superscripts, = +1 subscripts, etc.*/
  283.    int updat;   /* boolean to update ro_uf, ro_xf, ro_mcnt*/
  284.    {
  285.    char ch;
  286.    int l;
  287.    int xfs, ufs, mcnts;      /* save variables */
  288.    int cp2;         /* for tabulation calculation */
  289.    xfs = ro_xf; 
  290.    ufs = ro_uf; 
  291.    mcnts = ro_mcnt;
  292.    l = ro_bpos = ro_cp = ro_pp = 0;
  293.    while ( ch = ro_out2buf[ro_bpos] )
  294.       {
  295.       switch ( class( ch ))
  296.          {
  297.       case    ESCAPE:
  298.       case   BLACK:      /*print it if posssible*/
  299.          if ( ( ro_pp > ro_cp ) || ( l > lev ) )   
  300.             {
  301.             ro_cp++;
  302.             ro_bpos++;
  303.             break;
  304.             }
  305.          else      
  306.             {
  307.             while ( ro_cp > ro_pp )   
  308.                {
  309.                ro_outc(' ');
  310.                ro_pp++;
  311.                }
  312.             if ( ch == ro_scval[0] )
  313.                {
  314.                ro_outc(' ');
  315.                }
  316.             else 
  317.                {
  318.                ro_outc( ch );
  319.                }
  320.             ro_pp++;
  321.             if ( ro_mcnt > ro_ocnt )
  322.                {
  323.                ro_dbuf[ ro_bpos ] = ro_out2buf[ ro_bpos ];
  324.                if ( ro_bpos > ro_dpos ) 
  325.                   {
  326.                   ro_dpos = ro_bpos;
  327.                   }
  328.                }
  329.             ro_out2buf[ ro_bpos++ ] = ' ';
  330.             if ( ro_uf && ro_first )
  331.                {
  332.                ro_ubuf[ ro_ucol = ro_cp ] = UCHAR;
  333.                }
  334.             if ( ro_xf && ro_first ) 
  335.                {
  336.                ro_xbuf[ ro_xcol = ro_cp ] = XCHAR;
  337.                }
  338.             ro_blkcnt--; 
  339.             ro_cp++;
  340.             } 
  341.          break;
  342.  
  343.       case   WHITE:            /*assume blank*/
  344.          ro_cp++;
  345.          ro_bpos++;
  346.          break;
  347.  
  348.       case   TRANSLATE:      /*similar to BLACK and WHITE*/
  349.          ch = ro_out2buf[ ++ro_bpos ];
  350.          if ( ( ro_pp > ro_cp ) || ( l > lev ) || (ch == ' ') )
  351.             {
  352.             ro_cp++;
  353.             ro_bpos++;
  354.             break;
  355.             }
  356.          else
  357.             {
  358.             while ( ro_cp > ro_pp )
  359.                {
  360.                ro_outc( ' ' );
  361.                ro_pp++;
  362.                }
  363.             trch( ch );
  364.             ro_pp++;
  365.             if ( ro_mcnt > ro_ocnt )
  366.                {
  367.                ro_dbuf[ ro_bpos ] = ro_out2buf[ ro_bpos ];
  368.                ro_dbuf[ ro_bpos - 1 ] = ro_out2buf[ ro_bpos - 1 ];
  369.                if ( ro_bpos > ro_dpos ) 
  370.                   {
  371.                   ro_dpos = ro_bpos;
  372.                   }
  373.                }
  374.             ro_out2buf[ ro_bpos++ ] = ' ';
  375.             if ( ro_uf && ro_first )
  376.                {
  377.                ro_ubuf[ ro_ucol = ro_cp ] = UCHAR;
  378.                }
  379.             if ( ro_xf && ro_first )
  380.                {
  381.                ro_xbuf[ ro_xcol = ro_cp ] = XCHAR;
  382.                }
  383.             ro_blkcnt--; 
  384.             ro_cp++;
  385.             } 
  386.          break;
  387.  
  388.       case   SENTINEL: 
  389.          ro_out2buf[ ro_bpos ] = 0;
  390.          break;
  391.  
  392.       case   HTAB: 
  393.          for (cp2 = 0; ro_cp >= 0; cp2 += ro_tabsiz[0] )
  394.             {
  395.             ro_cp -= ro_tabsiz[ 0 ];
  396.             }
  397.          ro_cp = cp2; 
  398.          ro_bpos++; 
  399.          break;
  400.  
  401.       case   OTHERS:
  402.          if ( ro_verbose )
  403.             fprintf( stderr,"\nweird character value[octal]: %o\n",ch);
  404.          ro_bpos++;
  405.          break;
  406.          }
  407.       }
  408.  
  409.    if ( !updat )         /* restore original values */
  410.       {
  411.       ro_newxf = ro_xf;
  412.       ro_xf = xfs;
  413.       ro_newuf = ro_uf;
  414.       ro_uf = ufs;
  415.       ro_newmcnt = ro_mcnt;
  416.       ro_mcnt = mcnts;
  417.       }
  418.    }
  419.  
  420. /**************************************************/
  421. /* 3rd Mar, 85       */
  422. /* By Conrad Kwok   */
  423.  
  424. updatef()
  425.    {
  426.    ro_xf = ro_newxf;
  427.    ro_uf = ro_newuf;
  428.    ro_mcnt = ro_newmcnt;
  429.    }
  430.  
  431. /**************************************************/
  432.  
  433. int class( c )
  434.    char c;
  435.    {
  436.    if ( c == ro_tcval[0] ) 
  437.       {
  438.       return( TRANSLATE );
  439.       }
  440.    if ( c == ESCAPE ) 
  441.       {
  442.       return( ESCAPE );
  443.       }
  444.    if ( c > ' ' ) 
  445.       {
  446.       return( BLACK );
  447.       }
  448.    if ( c == BACKSPACE ) 
  449.       {
  450.       return( BLACK );
  451.       }
  452.    if ( c == ' ') 
  453.       {
  454.       return( WHITE );
  455.       }
  456.    if ( c == '\n' ) 
  457.       {
  458.       return( SENTINEL );
  459.       }
  460.    if ( c == '\r' ) 
  461.       {
  462.       return( SENTINEL );
  463.       }
  464.    if ( c == TAB ) 
  465.       {
  466.       return( HTAB );
  467.       }
  468.    if ( !c ) 
  469.       {
  470.       return( SENTINEL );
  471.       }
  472.    return ( OTHERS );
  473.    }
  474.  
  475. /**************************************************/
  476. /* put printer in fractional spacing mode;
  477.    set ro_frq */
  478.  
  479. fraction()   
  480.  
  481.    {
  482.    if ( !ro_frq && ro_frstring && ( ro_frval != 1 ))
  483.       {
  484.       outstr( ro_frstring );
  485.       ro_frq = TRUE;
  486.       }
  487.    }
  488.  
  489. /**************************************************/
  490. /* put printer in whole line spacing;
  491.    reset ro_frq */
  492.  
  493. whole()       
  494.    {
  495.    if ( ro_frq && ro_whstring )
  496.       {
  497.       outstr( ro_whstring );
  498.       ro_frq = FALSE;
  499.       }
  500.    }
  501.  
  502. /**************************************************/
  503. /* output string translation of c */
  504.  
  505. trch(c) 
  506. char c;
  507.    {
  508.    char *p;
  509.    if ( c < ' ' ) 
  510.       {
  511.       ro_outc( ro_tcval[ 0 ] );
  512.       ro_outc( c );
  513.       return;
  514.       }
  515.  
  516.    p = ro_tptr[ c - ' ' ];
  517.  
  518.    if ( p ) 
  519.       {
  520.       outstr( p );
  521.       }
  522.    else               /* not initialized */   
  523.       {
  524.       ro_outc( ro_tcval[ 0 ] );
  525.       ro_outc( '?' );
  526.       }
  527.    }
  528.  
  529. /****************************************/
  530. /* output printer control string for c */
  531.  
  532. pcont(c) 
  533.    char c;
  534.    {
  535.    char *p;
  536.    if ( c < ' ' ) 
  537.       {
  538.       ro_outc( ro_cfval[ 0 ] );
  539.       ro_outc( c );
  540.       return;
  541.       }
  542.  
  543.    p = ro_cptr[ c - ' ' ];
  544.  
  545.    if ( p ) 
  546.       {
  547.       outstr( p );
  548.       }
  549.    else               /* not initialized */
  550.       {
  551.       ro_outc( ro_cfval[0] );
  552.       ro_outc( '?' );
  553.       }
  554.    }
  555.  
  556. /****************************************************************
  557.  
  558.    ro_outc()   Output a single character to putchar()
  559.          or to the postprocessor.
  560.  
  561. ****************************************************************/
  562.  
  563. ro_outc( c )
  564.    int c;
  565.    {
  566.  
  567.    if ( ro_suppress == TRUE )
  568.       {
  569.       return;
  570.       }
  571.  
  572. #ifdef   POSTPROCESS
  573.    ro_post( c );
  574. #else
  575.    putchar( c );
  576. #endif
  577.  
  578.    }
  579.  
  580.